﻿using System;
using Newtonsoft.Json;
using Optum.SN.Infra.Core.TestBase.Properties;
using System.Net.Http.Formatting;

namespace Optum.SN.Infra.Core.TestBase.Utility
{
    /// <summary>
    /// Builds a serializer object, e.g., JSON, XML, etc.
    /// </summary>
    public static class SerializerBuilder
    {
        /// <summary>
        /// Builds a serializer object, e.g., JSON, XML, etc.
        /// </summary>
        /// <param name="dataTransferMedia">Identifies the serializer type to build.  Default value is application/json, which builds a JSON serializer.</param>
        /// <returns>Concrete serializer.</returns>
        public static ISerializer Build(string dataTransferMedia = null)
        {
            if (string.IsNullOrWhiteSpace(dataTransferMedia) || dataTransferMedia == Settings.Default.DataTransferMedia)
                return new JsonSerializer {DataTransferMedia = Settings.Default.DataTransferMedia};
            throw new Exception(string.Format("Media type, {0}, is currently unsupported.", dataTransferMedia.Trim()));
        }
    }
    /// <summary>
    /// Serializer object.
    /// </summary>
    public interface ISerializer
    {
        /// <summary>
        /// Gets/sets media type, e.g., application/json, etc.
        /// </summary>
        string DataTransferMedia { get; set; }
        /// <summary>
        /// Deserializes provided content to a specified type.
        /// </summary>
        /// <typeparam name="T">Type to deserialize to.</typeparam>
        /// <param name="content">Content to deserialize.</param>
        /// <returns>Typed content.</returns>
        T Deserialize<T>(string content);
        /// <summary>
        /// Gets media type formatter, e.g., <see cref="JsonMediaTypeFormatter"/>, etc.
        /// </summary>
        /// <returns>Media type formatter.</returns>
        MediaTypeFormatter GetFormatter();
    }
    /// <summary>
    /// Encapsulates common serializer API.
    /// </summary>
    public abstract class SerializerBase
    {
        /// <summary>
        /// Gets/sets media type, e.g., application/json, etc.
        /// </summary>
        public string DataTransferMedia { get; set; }
    }

    /// <summary>
    /// JSON serializer.
    /// </summary>
    public sealed class JsonSerializer : SerializerBase, ISerializer
    {
        /// <summary>
        /// Deserializes provided content to specified type.
        /// </summary>
        /// <typeparam name="T">Type to deserialize to.</typeparam>
        /// <param name="content">Content to deserialize.</param>
        /// <returns>Typed content.</returns>
        /// <remarks>It's a pass through method and forwards the call to <see cref="JsonConvert.DeserializeObject&lt;T&gt;(string)"/>.</remarks>
        public T Deserialize<T>(string content)
        {
            return JsonConvert.DeserializeObject<T>(content);
        }
        /// <summary>
        /// Gets <see cref="JsonMediaTypeFormatter"/>.
        /// </summary>
        /// <returns>JOSN Media type formatter.</returns>
        public MediaTypeFormatter GetFormatter()
        {
            return new JsonMediaTypeFormatter();
        }
    }
}